;; collection/table.scm - (c) rohan drape, 2000-2005

;; Extensions to the basic table at host/table.scm.

;; Make an entry in `table' for the association of `key' with `value'.
;; If `key' exists the new value is appended to the list of existing
;; values.

(define (table-put-append! t key value)
  (let ((r (table-get* t key)))
    (if r 
	(table-put! t key (cons value r))
	(table-put! t key (list value)))))

;; Remove all entries from `table'.

(define (table-clear! table)
  (table-for-each (lambda (key value) (table-remove! table key))
		  table))

;; Construct a <list> of all keys or values in `table'.

(define (table-keys t)   (table-map (lambda (k v) k) t))
(define (table-values t) (table-map (lambda (k v) v) t))

;; Translation with association lists.

(define (table->alistL t) (table-map list t))

(define (alistL->table a)
  (let ((t (make-table)))
    (for-each (lambda (l) (table-put! t (car l) (cadr l))) a)
    t))

;; Translation with property lists.

(define (table->plist t) (splice (table->alistL t)))
(define (plist->alistL l) (unfold null? (cut take <> 2) cddr l))
(define (plist->table l) (alistL->table (plist->alistL l)))

;; Make a new table that is a copy of `t'.  This copies only the table
;; structure, not the stored values.

(define (table-copy t) 
  (let ((t_ (make-table)))
    (table-for-each (lambda (k v) (table-put! t_ k v)) t)
    t_))

;; Make a table that has all key/value at all tables at `z'.

(define (table-merge . z)
  (let ((t (make-table)))
    (for-each 
     (lambda (zz)
       (table-for-each (lambda (k v) (table-put! t k v)) zz))
     z)
    t))

;; Add all key/value at all tables at `z' to t.

(define (table-merge! t . z)
  (for-each 
   (lambda (zz)
     (table-for-each (lambda (k v) (table-put! t k v)) zz))
   z))
